#include"contact.h"

static int FindByName(const Contact* pc, char name[]) {
	assert(pc);
	for (int i = 0; i < pc->count; i++) {
		if (strcmp(pc->data[i].name, name) == 0)
			return i;
	}
	return -1;
}

void CheckCapacity(Contact* pc)
{
	if (pc->capacity == pc->count) {
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
		if (ptr == NULL) {
			printf("AddContact::%s\n", strerror(errno));
			return;
		}
		else {
			pc->data = ptr;
			pc->capacity += 2;
		}
	}
}

void LoadContact(Contact* pc) {
	FILE* pfRead = fopen("contact.txt", "rb");
	if (pfRead == NULL) {
		perror("LoadContact");
		return;
	}

	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pfRead)) {
		CheckCapacity(pc);
		pc->data[pc->count] = tmp;
		pc->count++;
	}

	fclose(pfRead);
	pfRead = NULL;
}

//静态
//void InitContact(Contact* pc) {
//	assert(pc);
//	pc->count = 0;
//	memset(pc->data, 0, sizeof(pc->data));
//}

//动态
int InitContact(Contact* pc) {
	assert(pc);
	pc->count = 0;
	pc->data = (PeoInfo*)calloc(3, sizeof(PeoInfo));
	if (pc->data == NULL) {
		printf("InitContact::%s\n", strerror(errno));
		return 1;
	}
	pc->capacity = 3;
	//加载文件的信息到通讯录中
	LoadContact(pc);
	return 0;
}

//静态
//void AddContact(Contact* pc) {
//	assert(pc);
//
//	if (pc->count == MAX_SIZE) {
//		printf("通讯录已满，无法增加");
//		return;
//	}
//
//	printf("请输入名字->");
//	scanf("%s", pc->data[pc->count].name);
//	printf("请输入年龄->");
//	scanf("%d", &(pc->data[pc->count].age));
//	printf("请输入性别->");
//	scanf("%s", pc->data[pc->count].sex);
//	printf("请输入电话->");
//	scanf("%s", pc->data[pc->count].tel);
//	printf("请输入地址->");
//	scanf("%s", pc->data[pc->count].addr);
//
//	pc->count++;
//	printf("增加成功\n");
//}


//动态
void AddContact(Contact* pc) {
	assert(pc);

	//增容
	CheckCapacity(pc);

	printf("请输入名字->");
	scanf("%s", pc->data[pc->count].name);
	printf("请输入年龄->");
	scanf("%d", &(pc->data[pc->count].age));
	printf("请输入性别->");
	scanf("%s", pc->data[pc->count].sex);
	printf("请输入电话->");
	scanf("%s", pc->data[pc->count].tel);
	printf("请输入地址->");
	scanf("%s", pc->data[pc->count].addr);

	pc->count++;
	printf("增加成功\n");
}

void ShowContact(const Contact* pc) {
	assert(pc);
	int i = 0;
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	for (i = 0; i < pc->count; i++) {
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", 
			pc->data[i].name, 
			pc->data[i].age, 
			pc->data[i].sex, 
			pc->data[i].tel, 
			pc->data[i].addr);
	}
}

void DelContact(Contact* pc) {
	assert(pc);
	char name[MAX_NAME] = { 0 };
	if (pc->count == 0) {
		printf("通讯录为空，无法删除\n");
		return;
	}
	printf("请输入被删除人的姓名->");
	scanf("%s", name);
	//删除
	
	//1.查找
	int pos = FindByName(pc, name);
	if (pos == -1) {
		printf("不存在");
		return;
	}

	//2.删除
	for (int i = pos; i < pc->count - 1; i++) {
		pc->data[i] = pc->data[i + 1]; 
	}
	pc->count--;
	printf("删除成功\n");
}

void SearchContact(Contact* pc) {
	assert(pc);
	char name[MAX_NAME] = { 0 };
	printf("请输入查找姓名->");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
		printf("不存在");
	else {
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n",
				pc->data[pos].name,
				pc->data[pos].age,
				pc->data[pos].sex,
				pc->data[pos].tel,
				pc->data[pos].addr);
	}
	return;
}

void ModifyContact(Contact* pc) {
	assert(pc);
	char name[MAX_NAME] = { 0 };
	printf("请输入被修改人姓名->");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1) {
		printf("不存在");
		return;
	}

	//2.修改
	printf("开始修改\n");
	printf("请输入名字->");
	scanf("%s", pc->data[pos].name);
	printf("请输入年龄->");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入性别->");
	scanf("%s", pc->data[pos].sex);
	printf("请输入电话->");
	scanf("%s", pc->data[pos].tel);
	printf("请输入地址->");
	scanf("%s", pc->data[pos].addr);

	printf("修改成功");
}

int Cmp_By_Name(const void* e1, const void* e2) {
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}

void SortContact(Contact* pc) {
	assert(pc);
	qsort(pc->data, pc->count, sizeof(PeoInfo), Cmp_By_Name);
	printf("排序成功\n");
}

void DestroyContact(Contact* pc)
{
	assert(pc);
	free(pc->data);
	pc->data = NULL;
	pc = NULL;
}

void SaveContact(Contact* pc) {
	assert(pc);
	FILE* pfWrite = fopen("contact.txt", "wb");
	if (pfWrite == NULL) {
		perror("SaveContact");
		return;
	}
	//写文件
	for (int i = 0; i < pc->count; i++) {
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pfWrite);
	}

	fclose(pfWrite);
	pfWrite = NULL;
}

